No puedo entender cómo char *argv[] es similar a char **argv. También hágame saber cuándo usar punteros.
Un parámetro de función declarado con tipo de matriz se ajusta silenciosamente para tener tipo de puntero. Por lo tanto, si declara una función con un parámetro de tipo int x[] , el parámetro en realidad tiene tipo int *x . De manera similar, char *argv[] en un parámetro de función es lo mismo que char **argv ya que la matriz de punteros se ajusta de un puntero a otro.
Básicamente char * argv[] es una matriz de punteros char y char ** argv es un puntero a un puntero char.
Cuando lo pasamos como parámetro de función, char * argv[] se ajusta al tipo de puntero que apunta al elemento inicial de esa matriz, char ** argv y son las mismas cosas .
6.7.5.3 Declaradores de funciones (incluidos los prototipos) ...
7 La declaración de un parámetro como ''matriz de tipo'' se ajustará a ''puntero calificado a tipo'', donde los calificadores de tipo (si los hay) son los especificados entre [ y ] de la derivación del tipo de matriz. Si la palabra clave static también aparece dentro de [ y ] de la derivación del tipo de matriz, entonces, para cada llamada a la función, el valor del argumento real correspondiente proporcionará acceso al primer elemento de una matriz con al menos tantos elementos como se especifica por la expresión de tamaño.
Como puede ver, usamos ambas definiciones de main son equivalentes:
int main(int argc, char ** argv)Y
int main(int argc, char *argv[])